package com.collins.thread.practices.drawLottery;

import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

public class Host {
    // lock
    public static final Object lock = new Object();
    // data storing map for each thread
    public static Map<String, List> dataLocal = new HashMap<>();
    // thread storing map for each thread
    public static Map<String, Thread> threadLocal = new HashMap<>();
    // future task storing map for each thread
    public static Map<String, FutureTask> futureTaskLocal = new HashMap<>();
    // data for lottery
    public static List<Integer> lotteries;
    // box number
    public static final int boxNum = 4;
    // flag for switcher
    public static int flag = 0;
    // public rng
    public static Random random = new Random();

    public static void main(String[] args) {
        // add lotteries into list
        int[] money = new int[]{10, 30, 20, 100, 50, 200, 30, 130, 24, 56,
                37, 234, 455, 2, 40, 56, 12, 22, 33, 89, 10};
        lotteries = new ArrayList<>();
        for (int m : money) {
            lotteries.add(m);
        }
        System.out.println("total lotteries: " + lotteries);
        // printLotteries();
        findMaxLotteries();
    }

    public static void printLotteries() {
        // start all lottery box threads
        for (int i = 0; i < boxNum; i++) {
            Thread t = new Thread(new LotteryBox());
            String tName = "lottery box-" + i;
            t.setName(tName);
            // add data list into data map
            dataLocal.put(tName, new ArrayList<Integer>());
            threadLocal.put(tName, t);
            t.start();
        }
        Thread watcher = new Thread(new Watcher());
        watcher.setName("watcher");
        watcher.setDaemon(true);
        watcher.start();
    }

    public static void findMaxLotteries() {
        List<Integer> ttlMaxList = new ArrayList<>();
        for (int i = 0; i < boxNum; i++) {
            FutureTask<Integer> ft = new FutureTask<>(new LotteryBoxCallable());
            Thread t = new Thread(ft);
            String tName = "lottery box-" + i;
            t.setName(tName);
            threadLocal.put(tName, t);
            futureTaskLocal.put(tName, ft);
            t.start();
        }
        try {
            for (String key : futureTaskLocal.keySet()) {
                // use polling
                while(true){
                    FutureTask<Integer> ft = futureTaskLocal.get(key);
                    if(ft.isDone()){
                        Integer max = ft.get();
                        if (max != null) {
                            ttlMaxList.add(max);
                        }
                        // print maximum for each lottery box
                        System.out.println(key + "'s maximum lottery is: " + max);
                        break;
                    }else{
                        TimeUnit.MILLISECONDS.sleep(2000);
                        System.out.println("processing, please wait...");
                    }
                }
            }
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
        // print total maximum
        System.out.println("total maximum lottery is: " + Collections.max(ttlMaxList));
    }
}
